package com.relax;

import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiRobotSendRequest;
import com.dingtalk.api.response.OapiRobotSendResponse;
import org.apache.commons.codec.binary.Base64;
import redis.clients.jedis.Jedis;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.sql.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Objects;
import java.util.Set;
import java.util.logging.*;

public class MySQLRedisValidation {
    private static final String MYSQL_HOST = "10.192.241.60";
    private static final int MYSQL_PORT = 9964;
    private static final String MYSQL_USERNAME = "root";
    private static final String MYSQL_PASSWORD = "5P1+cOkv^W1a1P";
    private static final String MYSQL_DATABASE = "channel";
    private static final String MYSQL_DATABASE_SAAS_FORTRESS = "saas_fortress";

    private static final String REDIS_HOST = "10.192.241.16";
    private static final int REDIS_PORT = 9884;
    private static final String REDIS_PASSWORD = "af72kY_A_48QvS";

    private static final HashMap<String, ExistInfo> repeatSet = new HashMap<>();

    private static final String LOG_FILE_PATTERN = "redis-key-check.%g.log";
    private static final int MAXIMUM_FILES = 7;


    /**
     * 启动命令是  nohup java -jar check-redis-data.jar 3 &
     *
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        Integer interval = Integer.parseInt(args[0]);

        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.ALL);
        // 创建一个每天一个日志文件的 FileHandler
        Handler fileHandler = new FileHandler(LOG_FILE_PATTERN, 0, MAXIMUM_FILES, true);
        fileHandler.setFormatter(new SimpleFormatter());
        // 将 FileHandler 添加到 Logger 中
        logger.addHandler(fileHandler);


        while (true) {
            doCheck(logger);
            Thread.sleep(interval * 1000);
        }

    }

    private static void doCheck(Logger logger) throws SQLException {
        FileHandler fileHandler = null;
        ResultSet resultSet = null;
        Statement statement = null;
        Connection mysqlConnection = null;
        Jedis jedis = null;
        try {
            // 连接MySQL数据库
            mysqlConnection = DriverManager.getConnection(
                    "jdbc:mysql://" + MYSQL_HOST + ":" + MYSQL_PORT + "/" + MYSQL_DATABASE,
                    MYSQL_USERNAME, MYSQL_PASSWORD);

            // 执行查询
            statement = mysqlConnection.createStatement();
            String sqlQuery = "SELECT \n" +
                    "va.id as vpc_agent_id,\n" +
                    "va.vpc_id  as vpc_id, \n"+
                    "n.id as node_id\n" +
                    "from vpc_agent va \n" +
                    "inner join vpc vpc on va.vpc_id  = vpc.id\n" +
                    "INNER JOIN  node n on   n.cluster_id = vpc.cluster_ids ";
            resultSet = statement.executeQuery(sqlQuery);


            // 连接 Redis
            jedis = new Jedis(REDIS_HOST, REDIS_PORT);
            // 如果 Redis 有密码认证，需要进行认证
            jedis.auth(REDIS_PASSWORD);
            LocalDateTime now = LocalDateTime.now();
            // 遍历查询结果
            while (resultSet.next()) {
                // 执行 Redis 操作
                String vpc_agent_id = resultSet.getString("vpc_agent_id");
                String vpc_id = resultSet.getString("vpc_id");
                String node_id = resultSet.getString("node_id");
                // apiserver:noderoute/agents/08bdc7ae-1732-44f9-97a7-b0fc71fa85c5/nodes/673077cc-9561-4a22-b2bb-bc4f68d3523b
                String redisKey = "apiserver:noderoute/agents/" + vpc_agent_id + "/nodes/" + node_id;
                boolean exists = checkRedisExist(jedis, redisKey);
                ExistInfo existInfo = repeatSet.get(redisKey);
                if (null == existInfo) {
                    existInfo = new ExistInfo();
                    existInfo.setExist(exists);
                    existInfo.setLocalDateTime(now);
                    repeatSet.put(redisKey, existInfo);
                } else {
                    Boolean existBefore = existInfo.getExist();
                    if (!existBefore.equals(exists)) {
                        String tenantName = findTenant(vpc_id);
                        //状态不相同,需要发送到钉钉
                        String msg = "租户:"+tenantName+"\r\n"+
                                "agentId:" +vpc_agent_id + "状态发生改变\r\n"+

                                "上次状态:" + (existBefore ? "存在" : "不存在") + ",时间是:" + existInfo.getLocalDateTime() + " \r\n" +
                                "本次状态是:" + (exists ? "存在" : "不存在") + ",时间是:" + now +"\r\n";

                        logger.info(msg);
                        sendMsgToDingding(msg, logger);
                    }
                    existInfo.setExist(exists);
                    existInfo.setLocalDateTime(now);
                    repeatSet.put(redisKey, existInfo);
                }


//                String msg = "时间:" + now + ", redis的key:" + redisKey + " " + (exists ? "存在" : "不存在");
//                logger.info(msg);
            }
        } catch (Exception e) {
            logger.info("执行异常,异常信息是" + e.getMessage());
            e.printStackTrace();
        } finally {
            // 关闭数据库连接和Redis连接
            if (!Objects.isNull(resultSet)) {
                resultSet.close();
            }
            if (!Objects.isNull(statement)) {
                statement.close();
            }
            if (!Objects.isNull(mysqlConnection)) {
                mysqlConnection.close();
            }
            if (!Objects.isNull(jedis)) {
                jedis.close();
            }

            if (!Objects.isNull(fileHandler)) {
                // 关闭日志文件处理器
                fileHandler.close();
            }

        }
    }

    private static String findTenant(String vpcId) {
        ResultSet resultSet = null;
        PreparedStatement statement = null;
        Connection mysqlConnection = null;

        try {
            mysqlConnection = DriverManager.getConnection(
                    "jdbc:mysql://" + MYSQL_HOST + ":" + MYSQL_PORT + "/" + MYSQL_DATABASE_SAAS_FORTRESS,
                    MYSQL_USERNAME, MYSQL_PASSWORD);


            String sqlQuery = "select tenant_no ,tenant_name ,vpc_no  from saas_fortress.vpc_info where vpc_no =  ?";

            // 执行查询
            statement = mysqlConnection.prepareStatement(sqlQuery);
            statement.setString(1,vpcId);
            resultSet = statement.executeQuery();
            while (resultSet.next()) {
                // 处理查询结果
                String tenantName = resultSet.getString("tenant_name");
                return tenantName;
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            // 关闭数据库连接和Redis连接
            if (!Objects.isNull(resultSet)) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            if (!Objects.isNull(statement)) {
                try {
                    statement.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            if (!Objects.isNull(mysqlConnection)) {
                try {
                    mysqlConnection.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }

        }
        return null;
    }

    private static void sendMsgToDingding(String message, Logger logger) {
        String webhookUrl = "https://oapi.dingtalk.com/robot/send?access_token=6b8df85fca2f43689c1b655f2c40b20aaeb1758a5737250a9399ee3bc34d07cc";
        String secret = "SEC42b51e04f9af600e2cb211b4efb7eaacf748f5861b8807af19eb6c5e7c2ef32e";

        try {
            Long timestamp = System.currentTimeMillis();

            String stringToSign = timestamp + "\n" + secret;
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
            byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
            String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");


            webhookUrl = webhookUrl + "&timestamp=" + timestamp + "&sign=" + sign;

            System.out.println(sign);

            DingTalkClient client = new DefaultDingTalkClient(webhookUrl);
            OapiRobotSendRequest request = new OapiRobotSendRequest();
            request.setMsgtype("text");
            OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text();
            text.setContent(message);
            request.setText(text);
            OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
            OapiRobotSendResponse response = client.execute(request);
            System.out.println(response);
        } catch (Exception e) {
            logger.info("钉钉消息发送失败" + e.getMessage());
        }
    }

    private static boolean checkRedisExist(Jedis jedis, String redisKey) {
        return jedis.exists(redisKey);
    }
}
